import os
import logging
from dtos.result import Result
from utils.common_util import CommonUtil
from config import UPLOAD_MATERIAL_IMAGE_SIZE, FILE_URL
import img2pdf


class UploadUtil(object):

    def __init__(self, upload_path):
        self.upload_path = upload_path

    @classmethod
    def get_file_path_by_url(cls, url):
        """
        通过url获取文件路径
        :param url:
        :return:
        """
        try:
            if "//" not in url:
                return None
            file_path = "/".join(url.split("//")[-1].split("/")[1:])
            if "." not in file_path:
                return None
            return file_path
        except Exception as ex:
            logging.info("通过url获取文件路径异常，原因：%s" % str(ex))
            return None

    def image_upload(self, files, model, file_size):
        """
        上传图片接口，该接口仅支持图片文件上传
        :param files:
        :param model:
        :param file_size:
        :return:
        """
        if not files or "image" not in files.keys() or not files['image'][0]:
            return Result.error_result(message="图片文件不能为空，请检查图片文件的key是否为image")
        if not model:
            return Result.error_result(message="model不能为空")
        if int(file_size) > UPLOAD_MATERIAL_IMAGE_SIZE:
            return Result.error_result(message="图片过大，请上传不超过%sKB大小的图片" %
                                               str(int(UPLOAD_MATERIAL_IMAGE_SIZE // 1024)))
        image = files['image'][0]
        filename, content_type, body = image['filename'], image['content_type'], image['body']
        allow_format_list = ["image/png", "image/jpg", "image/jpeg"]
        if content_type not in allow_format_list:
            return Result.error_result(message="文件格式不符合要求")
        year, month, day = CommonUtil.get_current_year_month_day()
        year, month, day = str(year), str(month), str(day)
        new_filename = "%s.%s" % (str(CommonUtil.get_md5_by_str(body)), content_type.split("/")[-1])
        file_path = CommonUtil.get_path_by_system_version([self.upload_path, model, year, month, day, new_filename])
        dir_path = CommonUtil.get_path_by_system_version([self.upload_path, model, year, month, day])
        try:
            if not os.path.exists(dir_path):
                os.makedirs(dir_path)
            with open(file_path, 'wb') as f:
                f.write(body)
            data = {
                "url": file_path
            }
            return Result.success_result(message="图片上传成功", data=data)
        except Exception as ex:
            message = "上传图片失败，原因：%s" % str(ex)
            logging.info(message)
            return Result.error_result(message=message)

    def file_upload(self, files):
        """
        上传附件接口，该接口仅支持文件上传
        :param files:
        :return:
        """
        if not files or "word" not in files.keys() or not files['word'][0]:
            return Result.error_result(message="附件不能为空，请检查附件的key是否为image")

        word = files['word'][0]
        filename, content_type, body = word['filename'], word['content_type'], word['body']

        allow_format_list = ["pdf", "pdf/a", "pdf/x", "xfdf", "doc", "docx", "jpg", "png", "jpeg", "webp"]
        img_format_list = ["jpg", "png", "jpeg", "webp"]

        suffix = filename.split(".")[-1] if "." in filename else None
        if not suffix or suffix not in allow_format_list:
            return Result.error_result(message="文件格式不符合要求")
        year, month, day = CommonUtil.get_current_year_month_day()
        year, month, day = str(year), str(month), str(day)
        new_filename = "%s.%s" % (str(CommonUtil.get_md5_by_str(body)), suffix)
        file_path = CommonUtil.get_path_by_system_version([self.upload_path, year, month, day, new_filename])
        dir_path = CommonUtil.get_path_by_system_version([self.upload_path, year, month, day])
        try:
            if not os.path.exists(dir_path):
                os.makedirs(dir_path)

            if suffix in img_format_list:
                # 如果是图片格式，将其转换为 PDF
                pdf_file_path = file_path.replace(suffix, ".pdf")  # 新的文件路径，后缀改为 .pdf
                with open(file_path, 'wb') as f:
                    f.write(body)
                with open(pdf_file_path, "wb") as f:
                    f.write(img2pdf.convert(file_path))
                save_path = CommonUtil.get_path_by_system_version(
                    [FILE_URL, year, month, day, new_filename.replace(suffix, ".pdf")])
            else:
                # 如果不是图片格式，直接保存文件
                with open(file_path, 'wb') as f:
                    f.write(body)
                save_path = CommonUtil.get_path_by_system_version([FILE_URL, year, month, day, new_filename])

            return Result.success_result(message="附件已保存", data=save_path)

        except Exception as ex:
            message = "上传附件失败，原因：%s" % str(ex)
            logging.info(message)
            return Result.error_result(message=message)

    @classmethod
    def remove_file(cls, file_path):
        """
        删除指定文件
        :param file_path:
        :return:
        """
        try:
            os.remove(file_path)
            return Result.success_result()
        except Exception as ex:
            logging.info("删除文件异常，路径：%s，原因：%s" % (str(file_path), str(ex)))
            return Result.error_result(message="删除失败，没有找到该文件")
